package com.lhz.common.utils.file;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.lhz.common.utils.UUIDUtils;
import com.lhz.framework.exception.ServiceException;
import jakarta.activation.MimetypesFileTypeMap;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.sf.jmimemagic.Magic;
import net.sf.jmimemagic.MagicMatch;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
public class FileUtil {

    private static MimetypesFileTypeMap mimetypesFileTypeMap;
    private static final ResourceLoader RESOURCE_LOADER = new DefaultResourceLoader();

    public static void isChartPathExist(String dirPath) {
        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }


    public static boolean copyFile(String srcFileName, String descFileName) {
        return copyFileCover(srcFileName, descFileName, false);
    }

    public static boolean copyFileCover(String srcFileName, String descFileName, boolean cover) {
        File srcFile = new File(srcFileName);
        if (!srcFile.exists()) {
            log.debug("复制文件失败，源文件 " + srcFileName + " 不存在!");
            return false;
        } else if (!srcFile.isFile()) {
            log.debug("复制文件失败，" + srcFileName + " 不是一个文件!");
            return false;
        } else {
            File descFile = new File(descFileName);
            if (descFile.exists()) {
                if (!cover) {
                    log.debug("复制文件失败，目标文件 " + descFileName + " 已存在!");
                    return false;
                }

                log.debug("目标文件已存在，准备删除!");
                if (!delFile(descFileName)) {
                    log.debug("删除目标文件 " + descFileName + " 失败!");
                    return false;
                }
            } else if (!descFile.getParentFile().exists()) {
                log.debug("目标文件所在的目录不存在，创建目录!");
                if (!descFile.getParentFile().mkdirs()) {
                    log.debug("创建目标文件所在的目录失败!");
                    return false;
                }
            }


            boolean var9 = true;
            try (InputStream ins = Files.newInputStream(srcFile.toPath());
                 FileOutputStream outs = new FileOutputStream(descFile)) {

                byte[] buf = new byte[1024];

                int readByte;
                while ((readByte = ins.read(buf)) != -1) {
                    outs.write(buf, 0, readByte);
                }

                log.debug("复制单个文件 " + srcFileName + " 到" + descFileName + "成功!");
                return true;
            } catch (Exception var23) {
                log.debug("复制文件失败：" + var23.getMessage());
            }
            return false;
        }
    }

    public static boolean copyDirectory(String srcDirName, String descDirName) {
        return copyDirectoryCover(srcDirName, descDirName, false);
    }

    public static boolean copyDirectoryCover(String srcDirName, String descDirName, boolean cover) {
        File srcDir = new File(srcDirName);
        if (!srcDir.exists()) {
            log.debug("复制目录失败，源目录 " + srcDirName + " 不存在!");
            return false;
        } else if (!srcDir.isDirectory()) {
            log.debug("复制目录失败，" + srcDirName + " 不是一个目录!");
            return false;
        } else {
            String descDirNames = descDirName;
            if (!descDirName.endsWith(File.separator)) {
                descDirNames = descDirName + File.separator;
            }

            File descDir = new File(descDirNames);
            if (descDir.exists()) {
                if (!cover) {
                    log.debug("目标目录复制失败，目标目录 " + descDirNames + " 已存在!");
                    return false;
                }

                log.debug("目标目录已存在，准备删除!");
                if (!delFile(descDirNames)) {
                    log.debug("删除目录 " + descDirNames + " 失败!");
                    return false;
                }
            } else {
                log.debug("目标目录不存在，准备创建!");
                if (!descDir.mkdirs()) {
                    log.debug("创建目标目录失败!");
                    return false;
                }
            }

            boolean flag = true;
            File[] files = srcDir.listFiles();

            for (File file : files) {
                if (file.isFile()) {
                    flag = copyFile(file.getAbsolutePath(), descDirNames + file.getName());
                    if (!flag) {
                        break;
                    }
                }

                if (file.isDirectory()) {
                    flag = copyDirectory(file.getAbsolutePath(), descDirNames + file.getName());
                    if (!flag) {
                        break;
                    }
                }
            }

            if (!flag) {
                log.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 失败!");
                return false;
            } else {
                log.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 成功!");
                return true;
            }
        }
    }

    //多文件合并为一个
    public static boolean mergeFiles(String[] tempFiles, String finalDir, String finalFileName) {
        if (tempFiles != null && tempFiles.length > 0) {
            for (String tempFile : tempFiles) {
                if (!isFile(tempFile)) {
                    return false;
                }
            }

            File dir = new File(finalDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            File finalFile = new File(finalDir, finalFileName);
            String resultPath = finalFile.getAbsolutePath();
            if (tempFiles.length == 1) {
                return (new File(tempFiles[0])).renameTo(finalFile);
            } else {
                File[] files = new File[tempFiles.length];

                for (int i = 0; i < tempFiles.length; ++i) {
                    files[i] = new File(tempFiles[i]);
                }


                try (FileOutputStream fileOutputStream = new FileOutputStream(resultPath, true);
                     FileChannel resultFileChannel = fileOutputStream.getChannel()) {


                    for (File file : files) {
                        try (FileInputStream inputStream = new FileInputStream(file);
                             FileChannel blk = inputStream.getChannel()) {
                            resultFileChannel.transferFrom(blk, resultFileChannel.size(), blk.size());
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                            return false;
                        }
                    }

                    resultFileChannel.close();
                    return isFile(finalDir + "/" + finalFileName);
                } catch (IOException var11) {
                    log.error(var11.getMessage(), var11);
                    return false;
                }
            }
        } else {
            return false;
        }
    }

    public static boolean isDir(String dir) {
        File file = new File(dir);
        if (!file.exists()) {
            return false;
        } else {
            return file.isDirectory();
        }
    }

    public static boolean isFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return false;
        } else {
            return file.isFile();
        }
    }

    public static void division(String target, long cutSize, String tempDir) {
        File targetfile = new File(target);
        int num = targetfile.length() % cutSize == 0L ? (int) (targetfile.length() / cutSize) : (int) (targetfile.length() / cutSize + 1L);

        try (InputStream in = Files.newInputStream(targetfile.toPath());
             BufferedInputStream bis = new BufferedInputStream(in)) {

            BufferedOutputStream bos;
            String tempFilePrex = targetfile.getName().substring(0, targetfile.getName().lastIndexOf("."));

            File file = new File(tempDir);
            if (!file.exists()) {
                file.mkdirs();
            }
            //获取目标文件的后缀
            String suffix = target.substring(target.lastIndexOf("."));
            for (int i = 0; i < num; ++i) {
                File tmpFile = new File(tempDir, tempFilePrex + "_" + (i + 1) + suffix);

                bos = new BufferedOutputStream(Files.newOutputStream(tmpFile.toPath()));
                byte[] bytes;
                int count;
                if (cutSize <= 1024L) {
                    bytes = new byte[(int) cutSize];
                    count = 1;
                } else {
                    bytes = new byte[1024];
                    count = (int) (cutSize / 1024L);
                }

                int len;
                while (count > 0 && (len = bis.read(bytes)) != -1) {
                    bos.write(bytes, 0, len);
                    bos.flush();
                    --count;
                }

                if (cutSize % 1024L != 0L) {
                    bytes = new byte[(int) (cutSize % 1024L)];
                    len = bis.read();
                    bos.write(bytes, 0, len);
                    bos.flush();
                    bos.close();
                }
            }
        } catch (IOException var14) {
            log.error(var14.getMessage(), var14);
        }

    }

    public static String readFileToString(String classResourcePath) {
        try (InputStream in = (new ClassPathResource(classResourcePath)).getInputStream()) {

            String var3;
            var3 = IOUtils.toString(in, StandardCharsets.UTF_8);
            return var3;
        } catch (IOException var15) {
            log.warn("Error file convert: {}", var15.getMessage());
            return null;
        }
    }

    public static boolean delFile(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            log.debug(fileName + " 文件不存在!");
            return true;
        } else {
            return file.isFile() ? deleteFile(fileName) : deleteDirectory(fileName);
        }
    }

    private static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                log.debug("删除文件 " + fileName + " 成功!");
                return true;
            } else {
                log.debug("删除文件 " + fileName + " 失败!");
                return false;
            }
        } else {
            log.debug(fileName + " 文件不存在!");
            return true;
        }
    }

    public static boolean deleteDirectory(String dirName) {
        String dirNames = dirName;
        if (!dirName.endsWith(File.separator)) {
            dirNames = dirName + File.separator;
        }

        File dirFile = new File(dirNames);
        if (dirFile.exists() && dirFile.isDirectory()) {
            boolean flag = true;
            File[] files = dirFile.listFiles();

            for (File file : files) {
                if (file.isFile()) {
                    flag = deleteFile(file.getAbsolutePath());
                    if (!flag) {
                        break;
                    }
                } else if (file.isDirectory()) {
                    flag = deleteDirectory(file.getAbsolutePath());
                    if (!flag) {
                        break;
                    }
                }
            }

            if (!flag) {
                log.debug("删除目录失败!");
                return false;
            } else if (dirFile.delete()) {
                log.debug("删除目录 " + dirName + " 成功!");
                return true;
            } else {
                log.debug("删除目录 " + dirName + " 失败!");
                return false;
            }
        } else {
            log.debug(dirNames + " 目录不存在!");
            return true;
        }
    }

    public static boolean createFile(String descFileName) {
        File file = new File(descFileName);
        if (file.exists()) {
            log.debug("文件 " + descFileName + " 已存在!");
            return false;
        } else if (descFileName.endsWith(File.separator)) {
            log.debug(descFileName + " 为目录，不能创建目录!");
            return false;
        } else if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
            log.debug("创建文件所在的目录失败!");
            return false;
        } else {
            try {
                if (file.createNewFile()) {
                    log.debug(descFileName + " 文件创建成功!");
                    return true;
                } else {
                    log.debug(descFileName + " 文件创建失败!");
                    return false;
                }
            } catch (Exception var3) {
                log.error(var3.getMessage(), var3);
                log.debug(descFileName + " 文件创建失败!");
                return false;
            }
        }
    }

    public static boolean createDirectory(String descDirName) {
        String descDirNames = descDirName;
        if (!descDirName.endsWith(File.separator)) {
            descDirNames = descDirName + File.separator;
        }

        File descDir = new File(descDirNames);
        if (descDir.exists()) {
            log.debug("目录 " + descDirNames + " 已存在!");
            return false;
        } else if (descDir.mkdirs()) {
            log.debug("目录 " + descDirNames + " 创建成功!");
            return true;
        } else {
            log.debug("目录 " + descDirNames + " 创建失败!");
            return false;
        }
    }

    public static void writeToFile(String fileName, String content, boolean append) {
        try {
            FileUtils.write(new File(fileName), content, "utf-8", append);
            log.debug("文件 " + fileName + " 写入成功!");
        } catch (IOException var4) {
            log.debug("文件 " + fileName + " 写入失败! " + var4.getMessage());
        }

    }

    public static void writeToFile(String fileName, String content, String encoding, boolean append) {
        try {
            FileUtils.write(new File(fileName), content, encoding, append);
            log.debug("文件 " + fileName + " 写入成功!");
        } catch (IOException var5) {
            log.debug("文件 " + fileName + " 写入失败! " + var5.getMessage());
        }

    }

    //将base64转为文件
    public static void writeToFileByImageBase64(String fileName, String imageBase64) {
        String base64 = StrUtil.subAfter(imageBase64, "base64,", true);
        if (!StrUtil.isBlank(base64)) {
            byte[] data = Base64.decodeBase64(base64);
            File file = new File(fileName);

            try {
                FileUtils.writeByteArrayToFile(file, data);
            } catch (IOException var6) {
                log.error(var6.getMessage(), var6);
            }

        }
    }

    /**
     * 压缩文件，fileName为空时，压缩整个目录
     *
     * @param srcDirName   文件目录
     * @param fileName     文件名称
     * @param descFileName 压缩后压缩文件名称
     */
    public static void zipFiles(String srcDirName, String fileName, String descFileName) {
        Assert.notNull(srcDirName, "文件压缩失败，目录不存在!");

        File fileDir = new File(srcDirName);
        if (fileDir.exists() && fileDir.isDirectory()) {
            File descFile = new File(descFileName);

            try (FileOutputStream fileOutputStream = new FileOutputStream(descFile);
                 ZipOutputStream zouts = new ZipOutputStream(fileOutputStream)) {

                if (!"*".equals(fileName) && !"".equals(fileName) && fileName != null) {
                    File file = new File(fileDir, fileName);
                    if (file.isFile()) {
                        zipFilesToZipFile(srcDirName, file, zouts);
                    } else {
                        zipDirectoryToZipFile(srcDirName, file, zouts);
                    }
                } else {
                    zipDirectoryToZipFile(srcDirName, fileDir, zouts);
                }

                zouts.close();
                log.debug(descFileName + " 文件压缩成功!");
            } catch (Exception var8) {
                log.debug("文件压缩失败：" + var8.getMessage());
                log.error(var8.getMessage(), var8);
            }
        } else {
            log.debug("文件压缩失败，目录 " + srcDirName + " 不存在!");
        }
    }

    /**
     * @param zipFileName  解压压缩包名称
     * @param descFileName 解压后目录
     * @return
     */
    public static boolean unZipFiles(String zipFileName, String descFileName) {
        String descFileNames = descFileName;
        if (!descFileName.endsWith(File.separator)) {
            descFileNames = descFileName + File.separator;
        }

        try {
            ZipFile zipFile = new ZipFile(zipFileName);
            ZipEntry entry;
            String entryName;
            String descFileDir;
            byte[] buf = new byte[4096];
            Enumeration enums = zipFile.getEntries();

            while (true) {
                while (enums.hasMoreElements()) {
                    entry = (ZipEntry) enums.nextElement();
                    entryName = entry.getName();
                    descFileDir = descFileNames + entryName;
                    if (entry.isDirectory()) {
                        (new File(descFileDir)).mkdirs();
                    } else {
                        File descFile = new File(descFileDir);
                        descFile.getParentFile().mkdirs();
                        File file = new File(descFileDir);
                        try (OutputStream os = Files.newOutputStream(file.toPath());
                             InputStream is = zipFile.getInputStream(entry)) {
                            int readByte;
                            while ((readByte = is.read(buf)) != -1) {
                                os.write(buf, 0, readByte);
                            }
                        } catch (Exception e) {
                            throw new ServiceException("文件解压失败");
                        }
                    }
                }

                zipFile.close();
                log.debug("文件解压成功!");
                return true;
            }
        } catch (Exception var13) {
            log.debug("文件解压失败：" + var13.getMessage());
            return false;
        }
    }

    public static void zipDirectoryToZipFile(String dirPath, File fileDir, ZipOutputStream zouts) {
        if (fileDir.isDirectory()) {
            File[] files = fileDir.listFiles();
            if (files.length == 0) {
                ZipEntry entry = new ZipEntry(getEntryName(dirPath, fileDir));

                try {
                    zouts.putNextEntry(entry);
                    zouts.closeEntry();
                } catch (Exception var6) {
                    log.error(var6.getMessage(), var6);
                }

                return;
            }

            for (File file : files) {
                if (file.isFile()) {
                    zipFilesToZipFile(dirPath, file, zouts);
                } else {
                    zipDirectoryToZipFile(dirPath, file, zouts);
                }
            }
        }

    }

    public static void zipFilesToZipFile(String dirPath, File file, ZipOutputStream zouts) {
        FileInputStream fin;
        ZipEntry entry;
        byte[] buf = new byte[4096];
        if (file.isFile()) {
            try {
                fin = new FileInputStream(file);
                entry = new ZipEntry(getEntryName(dirPath, file));
                zouts.putNextEntry(entry);

                int readByte;
                while ((readByte = fin.read(buf)) != -1) {
                    zouts.write(buf, 0, readByte);
                }

                zouts.closeEntry();
                fin.close();
                log.debug("添加文件 " + file.getAbsolutePath() + " 到zip文件中!");
            } catch (Exception var8) {
                log.error(var8.getMessage(), var8);
            }
        }

    }

    private static String getEntryName(String dirPath, File file) {
        String dirPaths = dirPath;
        if (!dirPath.endsWith(File.separator)) {
            dirPaths = dirPath + File.separator;
        }

        String filePath = file.getAbsolutePath();
        if (file.isDirectory()) {
            filePath = filePath + "/";
        }

        int index = filePath.indexOf(dirPaths);
        return filePath.substring(index + dirPaths.length());
    }

    public static String getContentType(String fileName) {
        if (mimetypesFileTypeMap == null) {
            mimetypesFileTypeMap = new MimetypesFileTypeMap();
        }

        return mimetypesFileTypeMap.getContentType(fileName);
    }

    public static String getRealContentType(File file) {
        try {
            MagicMatch match = Magic.getMagicMatch(file, false, true);
            if (match != null) {
                return match.getMimeType();
            }
        } catch (Exception var2) {
            log.error(var2.getMessage(), var2);
        }

        return "";
    }

    //下载文件流
    public static void downloadFile(File file, HttpServletRequest request, HttpServletResponse response, String fileName) {
        if (file != null && file.exists() && file.length() > 0L) {
            try (RandomAccessFile randomFile = new RandomAccessFile(file, "r");
                 ServletOutputStream out = response.getOutputStream()) {

                long contentLength = randomFile.length();
                String range = request.getHeader("Range");
                long start = 0L;
                long end = 0L;
                if (range != null && range.startsWith("bytes=")) {
                    String[] values = range.split("=")[1].split("-");
                    start = Long.parseLong(values[0]);
                    if (values.length > 1) {
                        end = Long.parseLong(values[1]);
                    }
                }

                int requestSize;
                if (end != 0L && end > start) {
                    requestSize = Long.valueOf(end - start + 1L).intValue();
                } else {
                    requestSize = 2147483647;
                }

                response.setContentType(getContentType(file.getName()));
                boolean isPreview = "preview".equalsIgnoreCase(request.getParameter("source"));
                fileName = StrUtil.isBlank(fileName) ? file.getName() : fileName;
                response.addHeader("Content-Disposition", (!isPreview ? "attachment; " : "")
                        + "filename*=utf-8'zh_cn'" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
                response.setHeader("Accept-Ranges", "bytes");
                if (range == null) {
                    response.setHeader("Content-Length", String.valueOf(contentLength));
                } else {
                    response.setStatus(206);
                    long requestStart = 0L;
                    long requestEnd = 0L;
                    String[] ranges = range.split("=");
                    if (ranges.length > 1) {
                        String[] rangeDatas = ranges[1].split("-");
                        requestStart = Long.parseLong(rangeDatas[0]);
                        if (rangeDatas.length > 1) {
                            requestEnd = Long.parseLong(rangeDatas[1]);
                        }
                    }

                    long length;
                    if (requestEnd > 0L) {
                        length = requestEnd - requestStart + 1L;
                        response.setHeader("Content-Length", String.valueOf(length));
                        response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
                    } else {
                        length = contentLength - requestStart;
                        response.setHeader("Content-Length", String.valueOf(length));
                        response.setHeader("Content-Range", "bytes " + requestStart + "-" + (contentLength - 1L) + "/" + contentLength);
                    }
                }

                randomFile.seek(start);

                byte[] buffer;
                for (int needSize = requestSize; needSize > 0; needSize -= buffer.length) {
                    buffer = new byte[1024];
                    int len = randomFile.read(buffer);
                    if (needSize < buffer.length) {
                        out.write(buffer, 0, needSize);
                    } else {
                        out.write(buffer, 0, len);
                        if (len < buffer.length) {
                            break;
                        }
                    }
                }

                out.flush();
            } catch (IOException var51) {
                log.debug(var51.getMessage(), var51);
                var51.getMessage();
            }
        } else {
            throw new RuntimeException("文件为空或不存在！");
        }
    }

    public static String path(String path) {
        String p = StrUtil.replace(path, "\\", "/");
        List<String> split = StrUtil.split(p, "/");
        p = StrUtil.join("/", split);
        if (!StrUtil.startWithAny(p, "/") && StrUtil.startWithAny(path, "\\", "/")) {
            p = p + "/";
        }

        if (!StrUtil.endWithAny(p, "/") && StrUtil.endWithAny(path, "\\", "/")) {
            p = p + "/";
        }

        if (path != null && path.startsWith("/")) {
            p = "/" + p;
        }

        return p;
    }

    public static List<String> findChildrenList(File dir, boolean searchDirs) {
        List<String> files = new ArrayList<>();
        String[] var3 = Objects.requireNonNull(dir.list());
        int var4 = var3.length;

        for (String subFiles : var3) {
            File file = new File(dir + "/" + subFiles);
            if (searchDirs && file.isDirectory() || !searchDirs && !file.isDirectory()) {
                files.add(file.getName());
            }
        }

        return files;
    }

    public static String getFileName(String fileName) {
        return (new File(fileName)).getName();
    }

    public static String getFileNameWithoutExtension(String fileName) {
        return fileName != null && fileName.lastIndexOf(".") != -1 ? fileName.substring(0, fileName.lastIndexOf(".")) : null;
    }

    public static String getFileExtension(String fileName) {
        return fileName != null && fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != fileName.length() - 1 ? fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase() : null;
    }

    //获取base64文件类型
    public static String getFileExtensionByImageBase64(String imageBase64) {
        String extension;
        String type = StrUtil.subBetween(imageBase64, "data:", ";base64,");
        if (inStringIgnoreCase(type, "image/jpeg")) {
            extension = "jpg";
        } else if (inStringIgnoreCase(type, "image/gif")) {
            extension = "gif";
        } else {
            extension = "png";
        }

        return extension;
    }

    public static Long getFileSize(String filePath) {
        File file = new File(filePath);
        return file.exists() && file.isFile() ? file.length() : 0L;
    }

    //将文件文件字节大小进行转换
    public static String fileSizeConvertToStr(long fileSize) {
        String strFileSize;
        if (fileSize < 1024) {
            strFileSize = fileSize + "B";
            return strFileSize;
        }

        DecimalFormat df = new DecimalFormat("######0.00");

        if (fileSize < 1024 * 1024) {//KB
            strFileSize = df.format(((double) fileSize) / 1024) + "KB";
        } else if (fileSize < 1024 * 1024 * 1024) {//MB
            strFileSize = df.format(((double) fileSize) / (1024 * 1024)) + "MB";
        } else {//GB
            strFileSize = df.format(((double) fileSize) / (1024 * 1024 * 1024)) + "GB";
        }
        return strFileSize;

    }

    public static boolean checkFileSize(long fileSize, long maxSize) {
        double v = ((double) fileSize) / (1024 * 1024);
        return v <= maxSize;
    }

    public static String getProjectPath() {
        String projectPath;

        try {
            File file = RESOURCE_LOADER.getResource("").getFile();
            while (true) {
                File f = new File(path(file.getPath() + "/src/main"));
                if (f.exists()) {
                    break;
                }

                f = new File(path(file.getPath() + "/target/classes"));
                if (f.exists() || file.getParentFile() == null) {
                    break;
                }

                file = file.getParentFile();
            }

            projectPath = file.toString();

            if (StrUtil.isBlank(projectPath)) {
                projectPath = System.getProperty("user.dir");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(e.getMessage());
        }
        return projectPath;
    }

    public static String getWebappPath() {
        String webappPath = "";

        try {
            File file = RESOURCE_LOADER.getResource("").getFile();
            while (true) {
                File f = new File(path(file.getPath() + "/WEB-INF/classes"));
                if (f.exists()) {
                    break;
                }

                f = new File(path(file.getPath() + "/src/main/webapp"));
                if (f.exists()) {
                    return f.getPath();
                }

                if (file.getParentFile() == null) {
                    break;
                }

                file = file.getParentFile();
            }

            webappPath = file.toString();
        } catch (IOException var4) {
            log.error(var4.getMessage(), var4);
        }

        if (StrUtil.isBlank(webappPath)) {
            webappPath = System.getProperty("user.dir");
        }

        return webappPath;
    }

    //将磁盘的多个文件打包成压缩包保存在本地
    public static void zipDirFileToFile(List<Map<String, String>> pathList, String filePath, String saveName) {
        try {
            ZipArchiveOutputStream zous = getServletOutputFile(filePath, saveName);
            for (Map<String, String> map : pathList) {
                String fileName = map.get("name");
                File file = new File(map.get("path"));
                InputStream inputStream = Files.newInputStream(file.toPath());
                setByteArrayOutputStream(fileName, inputStream, zous);
            }
            zous.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    //将磁盘的多个文件打包成压缩包并输出流下载
    public static void zipDirFileToFile(List<Map<String, String>> pathList, HttpServletRequest request, HttpServletResponse response) {
        try {
            // 设置response参数并且获取ServletOutputStream
            ZipArchiveOutputStream zous = getServletOutputStream(response);

            for (Map<String, String> map : pathList) {
                String fileName = map.get("name");
                File file = new File(map.get("path"));
                InputStream inputStream = Files.newInputStream(file.toPath());
                setByteArrayOutputStream(fileName, inputStream, zous);
            }
            zous.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    //将网络url资源文件的多个文件打包成压缩包并输出流下载
    public static void zipUrlToFile(List<Map<String, String>> pathList, HttpServletRequest request, HttpServletResponse response) {
        try {
            // 设置response参数并且获取ServletOutputStream
            ZipArchiveOutputStream zous = getServletOutputStream(response);

            for (Map<String, String> map : pathList) {
                String fileName = map.get("name");
                InputStream inputStream = getInputStreamFromUrl(map.get("path"));
                setByteArrayOutputStream(fileName, inputStream, zous);
            }
            zous.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }


    //File、FileInputStream 转换为byte数组
    public static byte[] fileToByte(String filePath) {
        try {
            File file = new File(filePath);

            InputStream input = Files.newInputStream(file.toPath());

            byte[] byt = new byte[input.available()];

            int read = input.read(byt);

            return byt;
        } catch (Exception e) {
            throw new RuntimeException("文件转换失败!");
        }
    }

    public static byte[] fileToByte(File file) {
        try (InputStream input = Files.newInputStream(file.toPath())) {

            byte[] byt = new byte[input.available()];

            int read = input.read(byt);

            return byt;
        } catch (Exception e) {
            throw new RuntimeException("文件转换失败!");
        }
    }

    //将byte数组转换为InputStream
    public static InputStream byteToInput(byte[] byt) {
        return new ByteArrayInputStream(byt);
    }

    //将byte数组转换为File
    public static File byteToFile(byte[] byt) {
        try {
            File file = File.createTempFile(UUIDUtils.getUuId(), null);
            OutputStream output = Files.newOutputStream(file.toPath());

            BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);

            bufferedOutput.write(byt);
            bufferedOutput.flush();
            bufferedOutput.close();
            output.flush();
            output.close();
            return file;
        } catch (Exception e) {
            throw new RuntimeException("文件转换失败!");
        }
    }

    private static ZipArchiveOutputStream getServletOutputFile(String filePath, String saveName) throws Exception {

        File desFile = new File(filePath, saveName);

        if (!desFile.exists()) {
            desFile.getParentFile().mkdirs();
            desFile.createNewFile();
        }

        ZipArchiveOutputStream zous = new ZipArchiveOutputStream(desFile);
        zous.setUseZip64(Zip64Mode.AsNeeded);
        return zous;
    }


    private static ZipArchiveOutputStream getServletOutputStream(HttpServletResponse response) throws Exception {

        String outputFileName = "文件" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".zip";
        response.reset();
        response.setHeader("Content-Type", "application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(outputFileName, StandardCharsets.UTF_8));
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        ServletOutputStream out = response.getOutputStream();

        ZipArchiveOutputStream zous = new ZipArchiveOutputStream(out);
        zous.setUseZip64(Zip64Mode.AsNeeded);
        return zous;
    }

    private static void setByteArrayOutputStream(String fileName, InputStream inputStream, ZipArchiveOutputStream zous) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            baos.flush();
            byte[] bytes = baos.toByteArray();

            //设置文件名
            ZipArchiveEntry entry = new ZipArchiveEntry(fileName);
            zous.putArchiveEntry(entry);
            zous.write(bytes);
            zous.closeArchiveEntry();
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 通过网络地址获取文件InputStream
     *
     * @param path 地址
     * @return
     */
    private static InputStream getInputStreamFromUrl(String path) {
        URL url = null;
        InputStream is = null;
        try {
            url = new URL(path);
        } catch (MalformedURLException e) {
            log.error(e.getMessage(), e);
        }
        try {
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.connect();
            is = conn.getInputStream();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return is;
    }

    private static boolean inStringIgnoreCase(String str, String... strs) {
        if (str != null && strs != null) {
            int var3 = strs.length;

            for (String s : strs) {
                if (str.equalsIgnoreCase(s.trim())) {
                    return true;
                }
            }
        }

        return false;
    }
}
